// 压缩带宽持久化到数据库
const util = require('util');
const config = require('config');
const mysql = require('mysql');
const Promise = require('bluebird');
const moment = require('moment');
const redis = require('../lib/redis');
const surume = require('../lib/surume');
const { isValidTimeForCommand } = require('../lib/utility');
// DEBUG=kalifa-client* node scripts/persistence-common-stats.js  -t 'bandwidth_persistence_stats-2022-04' 'bandwidth_persistence_account_stats-2022-04' -a 138489 168478 14048 15690 19942 197813
const debug = require('debug')('kalifa-client:scripts:persistence-common-stats.js');
const validator = require('validator');
const { program, InvalidArgumentError } = require('commander');

// mysql数据库连接
const db_stats = mysql.createPool({
  connectionLimit: 20,
  host: config.mysql.upStats.host,
  port: config.mysql.upyun.port,
  user: config.mysql.upStats.user,
  password: config.mysql.upStats.password,
  database: config.mysql.upStats.database
});

program
  .description(`Compressed bandwidth persistence to the database. 
                -e.g. node scripts/persistence-common-stats.js -t 'bandwidth_persistence_stats-2022-04' 'bandwidth_persistence_account_stats-2022-04' -a 138489 168478 14048 15690 19942 197813`)
  .option('-t, --tables <tables...>', 'tables', (v, previous) => {
    const time = v.slice(-7);
    isValidTimeForCommand(time, 'YYYY-MM', true);
    return previous.concat([v]);
  }, [])
  .option('-a, --account_arr <account_arr...>', 'account arr', (v, previous) => {
    if (!validator.isInt(v)) {
      throw new InvalidArgumentError('Not an integer number');
    }
    return previous.concat([parseInt(v, 10)]);
  }, [])
  .action(async (options) => {
    debug(`start to run script with parameter. account_arr: ${JSON.stringify(options.account_arr)}, tables: ${JSON.stringify(options.tables)}`);
    await main (options.account_arr, options.tables);
  });

program.parseAsync(process.argv)
  .then(() => {
    console.log('DONE');
    process.exit(0);
  })
  .catch((err) => {
    console.error(err);
    process.exit(1);
  });

const pubtime = moment(new Date()).format('YYYY-MM-DD HH:mm:ss');
const time = Math.floor(Date.now() / 1000);

function incrBucketStats(bucket_id, domain, bandwidth_key, bandwidth_value, tables, callback) {
  const table_name = tables[0];
  var sql = util.format('INSERT INTO `%s` SET bucket_id = ?, domain = ?, pubtime = ?, bandwidth_key = ?, bandwidth_value = ? ' +
    'ON DUPLICATE KEY UPDATE bandwidth_key = bandwidth_key + ?, bandwidth_value = bandwidth_value + ?', table_name);

  db_stats.query(sql, [bucket_id, domain, pubtime, bandwidth_key, bandwidth_value, bandwidth_key, bandwidth_value], function (err) {
    return callback(err);
  });
}

function incrAccountStats(account_id, bandwidth_key, bandwidth_value, tables, callback) {
  const table_name = tables[1];
  var sql = util.format('INSERT INTO `%s` SET account_id = ?, pubtime = ?, bandwidth_key = ?, bandwidth_value = ?' +
    'ON DUPLICATE KEY UPDATE bandwidth_key = bandwidth_key + ?, bandwidth_value = bandwidth_value + ?', table_name);

  db_stats.query(sql, [account_id, pubtime, bandwidth_key, bandwidth_value, bandwidth_key, bandwidth_value], function (err) {
    return callback(err);
  });
}

async function main(account_arr, tables) {
  const incrBucketStatsAsync = Promise.promisify(incrBucketStats);
  const incrAccountStatsAsync = Promise.promisify(incrAccountStats);

  for (const account_id of account_arr) {
    // 找到账号下所有空间
    let { buckets } = await surume.callAsync('upyun.bucket.find', {since: 0, account_id: account_id});
    while (buckets.length) {
      let max_id = 0;
      max_id = buckets[0].bucket_id;
      for (const bucket of buckets) {
        // 找到空间下所有域名
        const { bucket_domains } = await surume.callAsync('upyun.bucket.domain.find', {bucket_id: bucket.bucket_id});
        for (const domain of bucket_domains) {
          try {
            await redis.set(`${domain}:totalRsize:${time - 300}`, '123');
            const bf_cp_bytes = await redis.get(`${domain}:totalRsize:${time - 300}`);
            const bandwidth_key = `${domain}:totalRsize:${time - 300}`;
            const bandwidth_value = Number(bf_cp_bytes) || 0;
            await incrBucketStatsAsync(bucket.bucket_id, domain, bandwidth_key, bandwidth_value, tables);
            await incrAccountStatsAsync(account_id, bandwidth_key, bandwidth_value, tables);
          } catch (err) {
            console.log(err.message);
          }
        }
      }
      const data = await surume.callAsync('upyun.bucket.find', {since: max_id, account_id: account_id});
      buckets = data.buckets;
    }
  }
}
